package com.example.security.aspect;

import com.example.security.annotation.DataScope;
import com.example.security.entity.SysUser;
import com.example.security.service.SecurityService;
import com.example.security.common.BaseQuery;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

/**
 * 数据权限处理切面
 * 主要用于处理被@DataPermission注解标注的方法
 * 在方法执行前进行数据权限的过滤
 */
@Slf4j
@Aspect
@Component
@RequiredArgsConstructor
public class DataPermissionAspect {

    private final SecurityService securityService;
    
    /**
     * 环绕通知,在方法执行前后进行处理
     * @param point 切点
     * @param dataScope 数据权限注解
     */
    @Around("@annotation(dataScope)")
    public Object around(ProceedingJoinPoint point, DataScope dataScope) throws Throwable {
        try {
            // 获取当前登录用户
            SysUser user = securityService.getCurrentUser();
            
            // 如果是超级管理员,不进行数据过滤
            if (securityService.isAdmin(user)) {
                return point.proceed();
            }
            
            // 获取数据权限的SQL过滤条件
            String sqlFilter = getDataPermissionSql(user, dataScope);
            
            // 注入数据权限到查询参数中
            if (sqlFilter != null && !sqlFilter.isEmpty()) {
                Object params = point.getArgs()[0];
                if (params instanceof BaseQuery) {
                    ((BaseQuery) params).setDataScopeSql(sqlFilter);
                }
            }
            
            return point.proceed();
        } catch (Exception e) {
            log.error("数据权限处理异常", e);
            return point.proceed();
        }
    }

    /**
     * 生成数据权限SQL
     * 根据用户的数据权限范围生成对应的SQL过滤条件
     */
    private String getDataPermissionSql(SysUser user, DataScope dataScope) {
        if (user == null || user.getDataScope() == null) {
            return null;
        }

        StringBuilder sqlFilter = new StringBuilder();
        String orgAlias = dataScope.orgAlias();
        String userAlias = dataScope.userAlias();
        
        switch (user.getDataScope()) {
            case "1": // 全部数据
                break;
            case "2": // 本机构及以下
                sqlFilter.append(String.format(
                    " AND %s.org_id IN (SELECT id FROM sys_org WHERE id = %d OR find_in_set(%d, parent_ids))",
                    orgAlias, user.getOrgId(), user.getOrgId()
                ));
                break;
            case "3": // 本机构
                sqlFilter.append(String.format(" AND %s.org_id = %d", orgAlias, user.getOrgId()));
                break;
            case "4": // 仅本人
                sqlFilter.append(String.format(" AND %s.user_id = %d", userAlias, user.getId()));
                break;
            default:
                break;
        }
        return sqlFilter.length() > 0 ? sqlFilter.toString() : null;
    }
} 